﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.UIEvent;
using VAdvantage.Grids;
using VAdvantage.Classes;
using VAdvantage.Editor;
using VAdvantage.Utility;
using System.Windows.Data;


namespace VAdvantage.Controls
{
    public class VTextBox : CTextBox, IControl, IContextMenuListener, IEditingControl
    {
        public enum TextType
        {
            Text,
            Password,
            MultiLine
        }




        public VTextBox()
            : base()
        {

        }


        public VTextBox(int ControlHeight)
            : base()
        {
            base.Height = ControlHeight;
        }


        public VTextBox(bool isSearch)
            : base()
        {
            _isSearch = isSearch;
        }


        #region declaration

        //VAdvantage.Framework.Editor editor;
        private String _columnName;
        private String _oldText;
        private String _initialText;
        private String _VFormat;
        /** Field Length				*/
        private int _fieldLength;
        /**	Obcure Setting				*/
        //private Obscure m_obscure = null;
        private volatile bool _setting = false;
        /**	Field in focus				*/
        private volatile bool m_infocus = false;
        private bool _mandatory = false;
        private bool _readOnly = false;
        private GridField _field;
        private int _displayType;
        ContextMenuStrip popupMenu;
        private bool _isSearch = false;

        private SolidColorBrush backColorBrush = new SolidColorBrush();
        private bool _focus;

        System.Windows.Data.Binding binding;

        private bool _isPassword = false;


        #endregion

        #region Private Methods

        private void DisplayMaskedCharacters()
        {
            int cursorPosition = this.SelectionStart;

            // This changes the Text property of the base TextBox class to display all Asterisks in the control
            base.Text = new string(_PasswordChar, _Text.Length);

            this.Select((cursorPosition > _Text.Length ? _Text.Length : cursorPosition), 0);
        }

        #endregion


        #region Properties




        private char _PasswordChar = '*';
        /// <summary>
        /// Indicates the character to display for password input.
        /// </summary>
        public char PasswordChar
        {
            get { return _PasswordChar; }
            set { _PasswordChar = value; }
        }

        #endregion





        public static readonly DependencyProperty ValueChangedProperty =
       DependencyProperty.Register("Value", typeof(String), typeof(VAdvantage.Controls.VTextBox), new PropertyMetadata((o, e) =>
       {
           ((VTextBox)o).SetValue((Object)e.NewValue);

       }));


        public Object Value
        {
            get
            {
                return ((VTextBox)GetValue(VTextBox.ValueChangedProperty));
            }
            set
            {
                SetValue(VTextBox.ValueChangedProperty, value);
            }
        }


        public event EventHandler VetoableChangeListener;


        public VTextBox(String columnName, bool mandatory, bool isReadOnly, bool isUpdateable,
        int displayLength, int fieldLength, String VFormat, String ObscureType)
            : this(columnName, mandatory, isReadOnly, isUpdateable,
                displayLength, fieldLength, VFormat, ObscureType, TextType.Text, DisplayType.Text)
        {
        }


        /// <summary>
        /// Standard Constructor
        /// </summary>
        /// <param name="columnName"></param>
        /// <param name="mandatory"></param>
        /// <param name="isReadOnly"></param>
        /// <param name="isUpdateable"></param>
        /// <param name="displayLength"></param>
        /// <param name="fieldLength"></param>
        /// <param name="VFormat"></param>
        /// <param name="ObscureType"></param>
        /// 
        public VTextBox(String columnName, bool mandatory, bool isReadOnly, bool isUpdateable,
        int displayLength, int fieldLength, String VFormat, String ObscureType, TextType type, int displayType)
            : this()
        {
            //this.Name = columnName;
            _columnName = columnName;
            _VFormat = VFormat;
            _fieldLength = fieldLength;
            _mandatory = mandatory;
            _displayType = displayType;

            //	Editable
            if (isReadOnly || !isUpdateable)
            {
                SetReadOnly(true);
                //this.Enabled = false;
            }
            else
            {
                SetReadOnly(false);
            }
            if (_displayType == DisplayType.String)
            {
                //this.Height = fieldLength < 300 ? 20 : 40;
            }

            if (_displayType == DisplayType.Text)
            {
                this.Multiline = true;
                this.Height = fieldLength < 200 ? 20 : (fieldLength < 300 ? 30 : 40);
            }
            else if (_displayType == DisplayType.TextLong)
            {
                this.Multiline = true;
                this.Height = 70;
            }
            if (type == TextType.Password)
            {

                _isPassword = true;
                //this.UseSystemPasswordChar = true;
            }
            //this.Width = displayLength < 30 ? 300 : 500;
            this.MaxLength = fieldLength;
            if (!DataBase.GlobalVariable.IsVisualEditor)
            {
                if (!_isPassword)
                    SetPopUp();
            }

            this.TextChanged += OnTextChanged;

        }

        public void SetPopUp()
        {
            popupMenu = new ContextMenuStrip();
            popupMenu.AddMenuListener(this);
            if (_columnName.Equals("Script"))
            {
                MenuItem menuEditor = new MenuItem();
                menuEditor.Header = Utility.Msg.GetMsg(Utility.Envs.GetCtx(), "Script");
                menuEditor.Icon = Envs.LoadImageSource("Editor16.png");
                menuEditor.Click += delegate
                {
                    OnMenu(new ContextMenuEvent("Script"));
                };
                popupMenu.Items.Add(menuEditor);
            }
            else if (!"Name".Equals(_columnName))
            {
                MenuItem menuEditor = new MenuItem();
                menuEditor.Header = Msg.GetMsg(Utility.Envs.GetCtx(), "Editor");
                menuEditor.Icon = Envs.LoadImageSource("Editor16.png");
                menuEditor.Click += delegate
                {
                    OnMenu(new ContextMenuEvent("Editor"));
                };
                popupMenu.Items.Add(menuEditor);
            }
            ContextMenuService.SetContextMenu(this, popupMenu);
        }

        //protected rride void OnTextChanged(EventArgs e)
        //{
        //    if (!_setting)
        //    {
        //        base.OnTextChanged(e);

        //        if (EditingControlDataGridView != null)
        //        {
        //            EditingControlValueChanged = true;
        //            EditingControlDataGridView.NotifyCurrentCellDirty(true);
        //            //EditingControlDataGridView.CurrentCell.Value = GetValue();
        //        }
        //        SetColor();

        //        if (VetoableChangeListener != null)
        //        {
        //            VetoableChangeListener(this, e);
        //            // this.SelectionStart = this.Text.Length;
        //        }
        //    }
        //}



        //Dispose
        //protected override void Dispose(bool disposing)
        //{
        //    base.Dispose(disposing);
        //    _field = null;
        //    if (menuEditor != null)
        //    {
        //        menuEditor.Dispose();
        //        menuEditor = null;
        //    }

        //    if (popupMenu != null)
        //    {
        //        popupMenu.Items.Clear();
        //        popupMenu.Dispose();
        //        popupMenu = null;
        //    }
        //    if (editor != null)
        //    {
        //        editor.Dispose();
        //        editor = null;
        //    }
        //    VetoableChangeListener = null;
        //}

        #region IContextMenuLisrtner
        public void OnMenu(ContextMenuEvent evt)
        {
            if ("Script".Equals(evt.GetContextEvent()))
            {
                MessageBox.Show("script");
            }
            else if ("Editor".Equals(evt.GetContextEvent()))
            {
                Framework.Editor editor = new Framework.Editor(Msg.GetMsg(Envs.GetCtx(), _field.GetHeader(), true), _field.GetFieldLength().ToString(), GetText(), this);
                editor.Closed += (s, e) =>
                {

                    bool? ret = editor.DialogResult;
                    if ((bool)ret)
                    {
                        _focus = true;
                        this.SetValue(editor.GetText());

                        if (EditingControlDataGridView != null)
                        {
                            EditingControlDataGridView.RaiseCellValueChanged(this);
                            _field.SetValue(this.Text);
                            ((DataUtil.DataObject)EditingControlDataGridView.SelectedItem).SetFieldValue(_columnName.ToUpper(), this.Text);
                        }
                        else
                        {
                            if (VetoableChangeListener != null)
                            {
                                VetoableChangeListener(this, EventArgs.Empty);
                            }

                        }
                        SetColor();
                        _focus = false;
                    }
                };

                editor.Show();
            }
            else if (evt.GetContextEvent() == ContextMenuStrip.PREFERENCE_EVENT)
            {
                if (Model.MRole.GetDefault().IsShowPreference())
                {
                    //opens Value preference window
                    Framework.ValuePreference obj = Framework.ValuePreference.Start(_field, GetValue());
                    if (obj != null)
                    {
                        obj.Show();
                    }
                }
                return;
            }
        }
        #endregion


        #region IControl

        /** Mandatory (default false)   */
        public bool GetIsMandatory()
        {
            return _mandatory;
        }
        public void SetIsMandatory(bool value)
        {
            _mandatory = value;
        }
        public bool GetIsReadonly()
        {
            return _readOnly;
        }
        public GridField GetField()
        {
            return _field;
        }
        public void SetField(GridField field)
        {
            _field = field;
            if (_field != null && Model.MRole.GetDefault().IsShowPreference() && (_displayType == DisplayType.String) && !_isPassword)
            {
                String columnName = _field.GetColumnName();
                if ("Name".Equals(columnName) || "Value".Equals(columnName) || "DocumentNo".Equals(columnName))
                { ;}
                else
                {
                    Framework.ValuePreference.AddPreferenceMenuItem(null, popupMenu);
                }
            }

        }
        public int GetDisplayType()
        {
            return _displayType;
        }
        public void SetDisplayType(int displayType)
        {
            _displayType = displayType;
        }
        public string GetName()
        {
            return this._columnName;
        }
        public object GetValue()
        {
            return this.Text;
        }
        public string GetText()
        {
            //if(type

            return this.Text;
        }
        public string GetSelectedText()
        {
            return this.SelectedText;
        }

        /// <summary>
        /// Set value
        /// </summary>
        /// <param name="value">value</param>
        public void SetValue(object value)
        {
            _setting = true;
            if (value == null)
                this.Text = "";
            else
                this.Text = value.ToString();
            SetColor();
            _setting = false;
        }


        private string _Text = string.Empty;
        public new string Text
        {
            get
            {
                if (_isPassword)
                {
                    return _Text;
                }
                else
                {
                    return base.Text;
                }
            }
            set
            {
                if (value == null)
                {
                    if (_isPassword)
                    {
                        _Text = "";
                    }
                    else
                    {
                        base.Text = "";
                    }
                }
                else
                {
                    if (_isPassword)
                    {
                        _Text = value;
                        DisplayMaskedCharacters();
                    }
                    else
                    {
                        base.Text = value;
                    }
                }
            }
        }


        public void SetReadOnly(bool readOnly)
        {
            _readOnly = readOnly;
            this.IsReadOnly = readOnly;
            this.IsTabStop = !readOnly;

            SetBackGround(readOnly);
        }

        public void SetBackGround(bool value)
        {
            if (value)
            {
                backColorBrush.Color = DataBase.GlobalVariable.READONLY_TEXT_BACK_COLOR;
                this.Background = backColorBrush;
            }
            else
            {
                backColorBrush.Color = DataBase.GlobalVariable.NORMAL_TEXT_BACK_COLOR;
                this.Background = backColorBrush;
                SetColor();
            }
        }

        public void SetName(string name)
        {
            this._columnName = name;
        }

        public bool IsDisabled()
        {
            return !this.IsEnabled;
        }

        public void SetDisabled(bool disabled)
        {
            this.IsEnabled = !disabled;
        }

        public int GetTabIndex()
        {
            return this.TabIndex;
        }

        public void SetTabindex(int tabindex)
        {
            this.TabIndex = tabindex;
        }

        public bool Visible
        {
            get
            {
                return this.Visibility == System.Windows.Visibility.Visible;
            }
            set
            {
                this.Visibility = value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            }
        }

        public bool Focused
        {
            get { return _focus; }
        }

        public bool Multiline
        {
            get;
            set;
        }


        private void SetColor()
        {
            if (_mandatory)
            {
                if (this.Text == "")
                {
                    backColorBrush.Color = DataBase.GlobalVariable.MANDATORY_TEXT_BACK_COLOR;
                    this.Background = backColorBrush;
                }
                else
                {
                    backColorBrush.Color = DataBase.GlobalVariable.NORMAL_TEXT_BACK_COLOR;
                    this.Background = backColorBrush;
                    if (_field != null)
                        _field.SetError(false);
                }
            }
        }

        #endregion


        #region function 

        void OnTextChanged(object sender, TextChangedEventArgs e)
        {

            if (!_focus)
                return;
            SetColor();

            if (_isPassword)
            {
                if (base.Text.Length >= _Text.Length)
                    _Text += base.Text.Substring(_Text.Length);
                else if (base.Text.Length == 1)
                {
                    _Text = base.Text;
                }
                else
                {
                    string newText = _Text.Substring(0, base.Text.Length - 1);
                    newText += base.Text.Substring(base.Text.Length-1);
                    _Text = newText;
                }
                DisplayMaskedCharacters();
            }

            if (EditingControlDataGridView != null)
            {
                EditingControlDataGridView.RaiseCellValueChanged(this);
                _field.SetValue(this.Text);
                ((DataUtil.DataObject)EditingControlDataGridView.SelectedItem).SetFieldValue(_columnName.ToUpper(), this.Text);
            }


            if (VetoableChangeListener != null)
            {
                VetoableChangeListener(this, EventArgs.Empty);
            }

        }

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            _focus = true;
        }

        protected override void OnLostFocus(RoutedEventArgs e)
        {
            base.OnLostFocus(e);
            _focus = false;
        }

        public void Dispose()
        {
            _field = null;
            if (popupMenu != null)
                popupMenu.Items.Clear();
            popupMenu = null;
            binding = null;
        }

        #endregion

        public String BindValue
        {
            set
            {
                binding = new Binding(value);
                binding.Mode = BindingMode.OneWay;
                this.SetBinding(VTextBox.ValueChangedProperty, binding);
            }
        }

        #region DataGridview Editing Control

        public VDataGrid EditingControlDataGridView
        {
            get;
            set;
        }

        public void SetValueInDataGridColumn(object value)
        {
            SetValue(value);
        }

        #endregion

        /// <summary>
        /// Key Down Event Handler
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            int cursorPosition = this.SelectionStart;
            int selectionLength = this.SelectionLength;
            base.OnKeyDown(e);

            if (_isPassword) //If password textBox
            {
                // Handle Delete and Backspace Keys Appropriately till Selection
                if (e.Key == System.Windows.Input.Key.Back
                    || e.Key == System.Windows.Input.Key.Delete)
                {
                    
                    bool ignore = false;
                    if (e.Key == Key.Back)
                    {
                        if (cursorPosition > 0)
                        {
                            cursorPosition -= 1;
                            selectionLength -= 1;
                        }
                        else if (selectionLength < 1)
                        {
                            ignore = true;
                        }
                    }

                    if (cursorPosition < _Text.Length)
                    {
                        if (!ignore)
                        {
                            _Text = _Text.Remove(cursorPosition, (selectionLength > 0 ? selectionLength : 1)); //remove selected Text 
                        }
                    }

                    base.Text = _Text;
                    this.Select((cursorPosition > _Text.Length ? _Text.Length : cursorPosition), 0);
                    DisplayMaskedCharacters();
                }
            }
        }
    }
}
